package init_manager

import (
	"context"
	"gitverse.ru/synapse/kubelatte/pkg/observability/logs"
	"gitverse.ru/synapse/kubelatte/pkg/operator"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"time"
)

type InitManager struct {
	ticker         *time.Ticker
	triggersExist  bool
	templatesExist bool
	scopesExist    bool
}

type InitManagerInterface interface {
	Start(ctx context.Context)
	Stop(ctx context.Context)
	CheckResources(ctx context.Context)
	DoesTriggersExist() bool
	DoesTemplatesExist() bool
	DoesScopesExist() bool
}

func GetInitManager() *InitManager {
	return &InitManager{
		triggersExist:  !operator.IsControllerNeeded("trigger"),
		templatesExist: !operator.IsControllerNeeded("template"),
		scopesExist:    !operator.IsControllerNeeded("scope"),
	}
}

func (m *InitManager) Start(ctx context.Context) {
	m.ticker = time.NewTicker(3 * time.Second)
	for {
		select {
		case <-m.ticker.C:
			m.CheckResources(ctx)
		case <-ctx.Done():
			m.Stop(ctx)
			return
		}

		if m.triggersExist && m.templatesExist && m.scopesExist {
			m.Stop(ctx)
			return
		}
	}
}

func (m *InitManager) Stop(ctx context.Context) {
	if m.ticker != nil {
		m.ticker.Stop()
	}
	ctx.Done()
}

func (m *InitManager) CheckResources(ctx context.Context) {
	if !m.triggersExist && operator.IsControllerNeeded("trigger") {
		m.triggersExist = CheckTriggers(ctx)
	}
	if !m.templatesExist && operator.IsControllerNeeded("template") {
		m.templatesExist = CheckTemplates(ctx)
	}
	if !m.scopesExist && operator.IsControllerNeeded("scope") {
		m.scopesExist = CheckScopes(ctx)
	}
}

func (m *InitManager) DoesTriggersExist() bool {
	return m.triggersExist
}

func (m *InitManager) DoesTemplatesExist() bool {
	return m.templatesExist
}

func (m *InitManager) DoesScopesExist() bool {
	return m.scopesExist
}

func CheckTriggers(ctx context.Context) bool {
	triggers, err := operator.Cl.Trigger(operator.OperatorNamespace).List(ctx, metav1.ListOptions{})
	if err != nil {
		logs.Errorf("[InitManager] Failed List triggers %s", err)
		return false
	}
	return len(triggers.Items) != 0
}

func CheckTemplates(ctx context.Context) bool {
	templates, err := operator.Cl.Template(operator.OperatorNamespace).List(ctx, metav1.ListOptions{})
	if err != nil {
		logs.Errorf("[InitManager] Failed List templates %s", err)
		return false
	}

	return len(templates.Items) != 0
}

func CheckScopes(ctx context.Context) bool {
	scopes, err := operator.Cl.Scope(operator.OperatorNamespace).List(ctx, metav1.ListOptions{})
	if err != nil {
		logs.Errorf("[InitManager] Failed List scopes %s", err)
		return false
	}

	return len(scopes.Items) != 0
}
